package com.yang.service.Impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yang.constants.SystemConstants;
import com.yang.domain.entity.Menu;
import com.yang.mapper.MenuMapper;
import com.yang.service.MenuService;
import com.yang.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;



/**
 * <p>
 * 菜单权限表(Menu)表服务实现类
 * </p>
 * @author yang
 * @date 2023/5/29
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Resource
    private MenuMapper menuMapper;

    @Override
    public List<String> selectPermsByUserId(Long userId) {
        //如果是管理员，直接返回所有权限
        if (SecurityUtils.isAdmin()){

            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
            //找到所有是菜单和按钮的选项
            queryWrapper.in(Menu::getMenuType, SystemConstants.MENU,SystemConstants.BUTTON);
            //并且是正常启用的
            queryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);
            //拿到所有菜单
            List<Menu> menus = list(queryWrapper);
            //获取所有的权限标识进行返回
            return menus.stream().map(Menu::getPerms).collect(Collectors.toList());
        }

        //2.如果不是，则按正常地查找逻辑
        return menuMapper.selectPermsByUserId(userId);
    }

    @Override
    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
        List<Menu> menuList;

        //1.判断是否是管理员
        if (SecurityUtils.isAdmin()){
            //是管理员，直接返回正常的所有的菜单树
            menuList = menuMapper.selectAllRouterMenu();

        }else {
            //不是，根据当前的用户id查询菜单树
            menuList = menuMapper.selectRouterMenuTreeByUserId(userId);
        }

        //构建完父菜单树，往里面添加子菜单
        menuList = buildMenuTree(menuList,0L);

        return menuList;
    }

    @Override
    public List<Menu> selectMenuList(Menu menu) {

        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        //1.可以针对菜单名进行模糊查询
        wrapper.like(StringUtils.hasText(menu.getMenuName()),Menu::getMenuName,menu.getMenuName());
        //2.可以针对菜单的状态进行查询
        wrapper.eq(StringUtils.hasText(menu.getStatus()),Menu::getStatus,menu.getStatus());
        //3.按照父菜单和orderNum进行排序
        wrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);

        return list(wrapper);

    }

    @Override
    public boolean hasChild(Long menuId) {

        LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Menu::getParentId,menuId);
        int count = count(wrapper);

        return count > 0;
    }

    @Override
    public List<Long> selectMenuListByRoleId(Long roleId) {
        return getBaseMapper().selectMenuListByRoleId(roleId);
    }

    private List<Menu> buildMenuTree(List<Menu> menuList, long parentId) {

        List<Menu> treeMenuList = new ArrayList<>();

        for (Menu menu : menuList) {
            //过滤掉不是父菜单的数据
            if (!menu.getParentId().equals(parentId)){
                continue;
            }
            //设置子菜单
            menu.setChildren(getChildren(menu,menuList));

            //数据添加
            treeMenuList.add(menu);
        }
        return treeMenuList;
    }


    /**
     * 往父菜单里面封装子菜单
     * @param parentMenu 父菜单
     * @param menuList 菜单集合
     * @return 封装结果
     */
    private List<Menu> getChildren(Menu parentMenu, List<Menu> menuList) {

        List<Menu> childrenList = new ArrayList<>();

        for (Menu menu : menuList) {
            //判断当前菜单是不是当前菜单所属
            if (!menu.getParentId().equals(parentMenu.getId())){
                continue;
            }

            parentMenu.setChildren(getChildren(menu,menuList));

            childrenList.add(menu);
        }

        return childrenList;
    }
}

